//
//  FlowRequest.swift
//  Employee
//
//  Created by swordjoy on 2017/6/27.
//  Copyright © 2017年 remotevillage. All rights reserved.
//

import Foundation
import SwiftyJSON
import Moya

struct FlowRequest: DataResultProtocol {
  
  static let shared = FlowRequest()

  func getFlowType(success: @escaping ([Flow]) -> (), failure: VoidClosure? = nil ) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
  
    let cancle = FlowProvider.request(FlowAPI.getFlowType) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        let temps = Flow.array(from: data.arrayValue)
        success(temps)
      }, overdue: { 
        let _ = FlowRequest.shared.getFlowType(success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func getFlowTypeDetail(id: String, success: @escaping ( (FlowDetail) -> () ), failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.getFlowTypeDetail(id: id)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        let temp = FlowDetail(json: data)
        success(temp)
      }, overdue: { 
        let _ = FlowRequest.shared.getFlowTypeDetail(id: id, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func getCheckList(model: FlowListSend, success: @escaping ( ([FlowList], PageModel) -> () ), failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.getCheckList(model: model)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        let temps = FlowList.array(from: data["elements"].arrayValue)
        let page = PageModel(json: data)
        success(temps, page)
      }, overdue: {
        let _ = FlowRequest.shared.getCheckList(model: model, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func getCopyList(model: FlowListSend, success: @escaping ( ([FlowList], PageModel) -> () ), failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.getCopyList(model: model)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        let temps = FlowList.array(from: data["elements"].arrayValue)
        let page = PageModel(json: data)
        success(temps, page)
      }, overdue: {
        let _ = FlowRequest.shared.getCopyList(model: model, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func getApplyList(model: FlowListSend, success: @escaping ( ([FlowList], PageModel) -> () ), failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.getApplyList(model: model)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        let temps = FlowList.array(from: data["elements"].arrayValue)
        let page = PageModel(json: data)
        success(temps, page)
      }, overdue: { 
        let _ = FlowRequest.shared.getApplyList(model: model, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func addFlow(model: FlowSend, success: @escaping VoidClosure, failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.addFlow(model: model)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        success()
      }, overdue: { 
        let _ = FlowRequest.shared.addFlow(model: model, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func getApplyDetail(id: String, success: @escaping ( (ApplyDetail) -> () ), failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.getApplyDetail(id: id)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        let temp = ApplyDetail(json: data)
        success(temp)
      }, overdue: {
        let _ = FlowRequest.shared.getApplyDetail(id: id, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle

  }
  
  func checkApply(model: CheckSend, success: @escaping VoidClosure, failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.checkApply(model: model)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        success()
      }, overdue: {
        let _ = FlowRequest.shared.checkApply(model: model, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func myCheck(page: String,success: @escaping ( ([FlowList], PageModel) -> () ), failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.myCheck(page: page)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      self.dataProtocol(with: result, success: { (data) in
        let temps = FlowList.array(from: data["elements"].arrayValue)
        let page = PageModel(json: data)
        success(temps, page)
      }, overdue: {
        let _ = FlowRequest.shared.myCheck(page: page, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func removeFlow(id: String, success: @escaping VoidClosure, failure: VoidClosure? = nil) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = FlowProvider.request(FlowAPI.removeFlow(id: id)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (_) in
        success()
      }, overdue: { 
        let _ = FlowRequest.shared.removeFlow(id: id, success: success, failure: failure)
      }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
}
